<?php

namespace App\Http\Services;

use App\Exceptions\ErrorCodeException;
use App\Exceptions\PublicException;
use App\Http\Model\FinanceRechargeOrder;
use App\Http\Model\Hint;
use Illuminate\Support\Facades\Log;

/**
 * 银联云闪付退款
 *
 * Created on 2021/11/26 16:27
 * @Author <yuxiang.zhu@asiainnovations.net>
 */
class UnionPayRefundOrderServices extends CommonServices
{
    /**
     * 构造函数
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 退款
     *
     * Created at 2021/11/26 18:16
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param int $orderId
     * @throws ErrorCodeException
     */
    public function refund(int $orderId)
    {
        if (!$orderId) {
            throw new ErrorCodeException(Hint::PARAM_ERROR);
        }

        $model = new FinanceRechargeOrder();
        $order = $model->getOrder($orderId);
        if (!$order) {
            throw new ErrorCodeException(Hint::PARAM_ERROR);
        }

        if ($order['status'] != $model::STATUS_OF_SUCCESS) {
            throw new ErrorCodeException(Hint::UNION_PAY_ORDER_STATUS_CHANGED);
        }

        $config = config('pay');
        $config = $config['union_pay'];
        $orderSn = $config['msgSrcId'] . $order['order_sn'];//共29位
        $params = [
            'msgSrc' => $config['msgSrc'],
            'msgType' => 'refund',
            'requestTimestamp' => date('Y-m-d H:i:s'),
            'merOrderId' => $orderSn,
            'mid' => $config['mid'],
            'tid' => $config['tid'],
            'instMid' => $config['instMid'],
            'refundAmount' => $order['price'],
            'signType' => 'SHA256',//不要填MD5
        ];
        ksort($params);
        $query = '';
        foreach ($params as $key => $value) {
            $query .= $key . '=' . $value .'&';
        }
        $query = substr($query, 0, -1);
        $params['sign'] = strtoupper(hash('sha256', $query . $config['md5_key']));
        write_log('unionPay', 'refund', ['params' => $params]);
        $result = curl_request($config['refund_order_url'], $params, 'json');
        write_log('unionPay', 'refund', ['request_result' => $result]);
        if (strpos($result, 'refundStatus') !== false) {
            $resultArr = json_decode($result, true);
            if ($resultArr['refundStatus'] == 'SUCCESS') {//调用成功, 更改订单状态
                FinanceRechargeOrder::query()->where(['order_id' => $orderId])->update(['status' => $model::STATUS_OF_REFUNDED]);
            } else {
                write_log('unionPay', 'refund', ['refund_error' => $result]);
                throw new PublicException($resultArr['errMsg'] ?? '退款失败');
            }
        } else {
            throw new ErrorCodeException(Hint::UNION_PAY_REFUNDED_FAIL);
        }
    }
}